home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / news / inn1.000 / inn1.4sec-linux-src.tar / inn / frontends / decode.c < prev    next >
C/C++ Source or Header  |  1993-03-18  |  4KB  |  169 lines

  1. /*
  2. **  Decode seven-bit input into full binary output.
  3. **  From @(#)decode.c 1.3 5/15/85, distributed with B2.11 News.
  4. **
  5. **  Collect runs of 12 seven-bit characters.  Combine them in pairs to
  6. **  make six 13-bit characters.  Extract the top bit of each pair to make
  7. **  a 13th six-bit character, and split the remaining six 12-bit
  8. **  characters to form 12 six-bit characters.  Collect four six-bit
  9. **  characters and convert it to three eight-bit characters.
  10. **
  11. **  Got that?  All the remaining work in this program is to get the
  12. **  ending conditions right.
  13. */
  14. #include "configdata.h"
  15. #include <stdio.h>
  16. #include <sys/types.h>
  17. #include "clibrary.h"
  18.  
  19.  
  20. /*
  21. **  These characters can't appear in normal output, so we use them to
  22. **  mark that the data that follows is the terminator.  The character
  23. **  immediately following this pair is the length of the terminator (which
  24. **  otherwise might be indeterminable)
  25. */
  26. #define ENDMARK1    ((90 * 91 + 90) / 91)
  27. #define ENDMARK2    ((90 * 91 + 90) % 91)
  28.  
  29.  
  30. static char    Buffer[4];
  31. static int    count;
  32.  
  33.  
  34. static void
  35. pack6(n, last)
  36.     register int    n;
  37.     int            last;
  38. {
  39.     register char    *q;
  40.     register int    i;
  41.     char        b3[3];
  42.  
  43.     i = 3;
  44.     if (last && (i = Buffer[n - 1]) >= 3) {
  45.     /* Do the best we can. */
  46.     (void)fprintf(stderr, "Badly-terminated file.\n");
  47.     i = 3;
  48.     }
  49.  
  50.     b3[0] = (Buffer[0] << 2) | ((Buffer[1] >> 4) & 0x03);
  51.     b3[1] = (Buffer[1] << 4) | ((Buffer[2] >> 2) & 0x0F);
  52.     b3[2] = (Buffer[2] << 6) | ( Buffer[3]       & 0x3F);
  53.     for (q = b3; --i >= 0; )
  54.     (void)putchar(*q++);
  55. }
  56.  
  57.  
  58. static void
  59. pack12(p, n, last)
  60.     register char    *p;
  61.     register int    n;
  62.     int            last;
  63. {
  64.     register char    *q;
  65.     register int    c13;
  66.     register int    c;
  67.     register int    i;
  68.     char        b13[13];
  69.     char        b3[3];
  70.  
  71.     for (q = b13, c13 = 0, i = 0; i < n; i += 2) {
  72.     c = *p++ * 91;
  73.     c += *p++;
  74.     c13 <<= 1;
  75.     if (c & (1 << 12))
  76.         c13 |= 1;
  77.     *q++ = (c >> 6) & 0x3F;
  78.     *q++ = c & 0x3F;
  79.     }
  80.     *q++ = (char)c13;
  81.     if (last)
  82.     q = &b13[last];
  83.  
  84.     for (p = b13, n = q - p, i = count, q = &Buffer[count]; --n > 0; ) {
  85.     *q++ = *p++;
  86.     if (++i == 4) {
  87.         /* Inline expansion of pack6. */
  88.         b3[0] = (Buffer[0] << 2) | ((Buffer[1] >> 4) & 0x03);
  89.         b3[1] = (Buffer[1] << 4) | ((Buffer[2] >> 2) & 0x0F);
  90.         b3[2] = (Buffer[2] << 6) | ( Buffer[3]       & 0x3F);
  91.         (void)putchar(b3[0]);
  92.         (void)putchar(b3[1]);
  93.         (void)putchar(b3[2]);
  94.         i = 0;
  95.         q = Buffer;
  96.     }
  97.     }
  98.  
  99.     /* The last octet. */
  100.     *q++ = *p++;
  101.     i++;
  102.  
  103.     if (last || i == 4) {
  104.     pack6(i, last);
  105.     i = 0;
  106.     }
  107.  
  108.     count = i;
  109. }
  110.  
  111.  
  112. /* ARGSUSED0 */
  113. int
  114. main(ac, av)
  115.     int            ac;
  116.     char        *av[];
  117. {
  118.     register int    c;
  119.     register char    *p;
  120.     register int    i;
  121.     register int    first;
  122.     register int    cnt;
  123.     char        *base;
  124.     char        b12[12];
  125.     char        c12[12];
  126.  
  127.     base = p = b12;
  128.     for (i = 12, cnt = 0, first = 1; (c = getchar()) != EOF; ) {
  129.     if (c < ' ' || c >= ' ' + 91) {
  130.         (void)fprintf(stderr, "decode: Bad data\n");
  131.         exit(1);
  132.     }
  133.     if (i == 10 && p[-1] == ENDMARK1 && p[-2] == ENDMARK2) {
  134.         cnt = c - ' ';
  135.         i = 12;
  136.         p -= 2;
  137.         continue;
  138.     }
  139.     *p++ = c - ' ';
  140.     if (--i == 0) {
  141.         if (p == &b12[12]) {
  142.         if (!first)
  143.             pack12(c12, 12, 0);
  144.         else
  145.             first = 0;
  146.         base = p = c12;
  147.         }
  148.         else {
  149.         pack12(b12, 12, 0);
  150.         base = p = b12;
  151.         }
  152.         i = 12;
  153.     }
  154.     }
  155.  
  156.     if (base == b12) {
  157.     if (!first)
  158.         pack12(c12, 12, i == 12 ? cnt : 0);
  159.     }
  160.     else
  161.     pack12(b12, 12, i == 12 ? cnt : 0);
  162.  
  163.     if (i != 12)
  164.     pack12(base, 12 - i, cnt);
  165.  
  166.     exit(0);
  167.     /* NOTREACHED */
  168. }
  169.